﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Search3ForExcel.Searching;
using Search3ForExcel.Settings;
using System.ComponentModel.Composition;
using DotSpatial.Data;
using DotSpatial.Projections;
using DotSpatial.Controls;
using System.Diagnostics;
using System.IO;

namespace Search3ForExcel
{
    public partial class Search3ForExcelControl : UserControl
    {
        Map mapResult;

        public Map MapResult
        {
            get { return mapResult; }
            set { mapResult = value; }
        }

        SearchResult resultFs = null;
        
        Search3ForExcel.SearchPlugin searchUtil = new Search3ForExcel.SearchPlugin();  
        private Searcher _searcher;
        public readonly SearchSettings _searchSettings = new SearchSettings();
        private const string KEYWORDS_SEPARATOR = ";";

        [Import("Shell")]
        private ContainerControl Shell { get; set; }
        public Search3ForExcelControl()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            bool KeywordChk =true;

            _searchSettings.AreaSettings.Polygons = null;


            if (_searcher == null)
            {
                _searcher = new Searcher(Shell);
                // _searcher.Completed += _searcher_Completed;
            }

            //When?
            //-----------------------------------------------------
            _searchSettings.DateSettings.EndDate = DateTime.Today;
            DateTime nDaysAgo = DateTime.Today.AddDays(-365 * 5);
            _searchSettings.DateSettings.StartDate = nDaysAgo;

            //Where?
            //------------------------------------------------------
            double x1 = -12601641.49;
            double y1 = 4948244.62;
            double x2 = -12417745.49;
            double y2 = 5121231.28;

            Extent ext = new Extent(x1, y1, x2, y2);
            ProjectionInfo myProjection = new ProjectionInfo();
            ProjectionInfo target = KnownCoordinateSystems.Projected.World.WebMercator;
            myProjection = KnownCoordinateSystems.Geographic.World.WGS1984;
            _searchSettings.AreaSettings.SetAreaRectangle(ext, target);

            //Which parameters?
            //------------------------------------------------------
            
            IList<string> selectedKeywords;
            var text = string.IsNullOrWhiteSpace(cmbKeywords.Text) ? null : cmbKeywords.Text;

            if (string.IsNullOrWhiteSpace(text))
            {
                selectedKeywords = null;
            }
            else
            {
                selectedKeywords = text.Split(new[] { KEYWORDS_SEPARATOR }, StringSplitOptions.RemoveEmptyEntries)
                    .Select(k => k.Trim())
                    .ToList();
                // Remove duplicates
                selectedKeywords = selectedKeywords.Distinct().ToList();

                // Iterate keywords to find invalid keywords and replace existing by synonyms
                var toDelete = new List<string>();
                for (int i = 0; i < selectedKeywords.Count; i++)
                {
                    var cur = selectedKeywords[i];
                    // Try to find keyword
                    var orginal = _searchSettings.KeywordsSettings.Keywords.FirstOrDefault(
                        k => string.Equals(k, cur, StringComparison.OrdinalIgnoreCase));
                    if (orginal != null)
                    {
                        // Replace keyword by synonyms

                        selectedKeywords[i] = _searchSettings.KeywordsSettings.FindSynonym(orginal);
                    }
                    else
                    {
                        toDelete.Add(cur);
                    }
                }
                if (toDelete.Count > 0)
                {
                    var res = MessageBox.Show(Shell,
                                    "The next invalid Keywords will be removed from the search criteria:" +
                                    Environment.NewLine +
                                    String.Join(KEYWORDS_SEPARATOR + " ", toDelete),
                                    "Keywords not valid", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                    if (res != DialogResult.OK)
                    {
                        KeywordChk = false;
                    }
                    toDelete.ForEach(k => selectedKeywords.Remove(k));
                }
            }

            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            //kasem Step3: Which parameters?
            _searchSettings.KeywordsSettings.SelectedKeywords = selectedKeywords;
            
            //_searchSettings.KeywordsSettings.Keywords = searchUtil.setSearchParameter(cmbKeywords.Text);

            _searcher.KSearchResult = resultFs; 
            // Run search
            _searcher.Run(_searchSettings);
            /*
            foreach (var item in resultFs.ResultItems)
            {
                MessageBox.Show(item.FeatureSet.Projection.ToString() );
            }
                
            var layers = ShowSearchResults(resultFs);  
             */ 
        }

        private IEnumerable<IMapPointLayer> ShowSearchResults(SearchResult searchResult)
        {
            //try to save the search result layer and re-add it
            var hdProjectPath = HydroDesktop.Configuration.Settings.Instance.CurrentProjectDirectory;
            String timeStamp = string.Format("{0}_{1}{2}{3}",
                DateTime.Now.Date.ToString("yyyy-MM-dd"), DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);

            var loadedFeatures = new List<SearchResultItem>(searchResult.ResultItems.Count());
            Debug.WriteLine(searchResult.ResultItems.Count());
            foreach (var key in searchResult.ResultItems)
            {
                hdProjectPath = @"C:\Shapefile\Temp";
                Debug.WriteLine("hdProjectPath: " + hdProjectPath + "/Search Results");
                Debug.WriteLine("The other part: " + string.Format(Properties.Settings.Default.SearchResultNameMask, key.ServiceCode, timeStamp));
                var fs = key.FeatureSet;

                var filename = Path.Combine(hdProjectPath + "\\Search Results",
                                            string.Format(Properties.Settings.Default.SearchResultNameMask, key.ServiceCode, timeStamp));
                fs.Filename = filename;
                fs.Save();
                loadedFeatures.Add(new SearchResultItem(key.ServiceCode, FeatureSet.OpenFile(filename)));
            }
            Debug.WriteLine("Loop done.");

            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            var searchLayerCreator = new SearchLayerCreator(MapResult, new SearchResult(loadedFeatures), _searchSettings);
            return searchLayerCreator.Create();
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

        }


        private void button2_Click(object sender, EventArgs e)
        {
//            MessageBox.Show(resultFs.ResultItems.FeatureSet.ToString());
            //rbSelect_Click(this, new EventArgs());
            //rbSelect.Toggle();

            //if (e.Result == null) return;
            //e.ProgressHandler.ReportMessage("Adding Sites to Map...");
            resultFs = _searcher.KSearchResult;


            //We need to reproject the Search results from WGS84 to the projection of the map.
            var wgs84 = KnownCoordinateSystems.Geographic.World.WGS1984;
            foreach (var item in _searcher.KSearchResult.ResultItems)
                item.FeatureSet.Projection = wgs84;
            var layers = ShowSearchResults(_searcher.KSearchResult);
            //Debug.WriteLine("ShowSearchResults done.");

            // Unselect all layers in legend (http://hydrodesktop.codeplex.com/workitem/8559)
            //App.Map.MapFrame.GetAllLayers().ForEach(r => r.IsSelected = false);

            // Select first search result layer
        }

        private void Search3ForExcelControl_Load(object sender, EventArgs e)
        {

        }
    }
}
